// 内存文件系统（ramdisk）实现
// 用于测试，不需要真实磁盘

#include "types.h"
#include "riscv.h"
#include "defs.h"
#include "param.h"
#include "spinlock.h"
#include "memlayout.h"
#include "fs/buf.h"
#include "fs/fs.h"
#include "string.h"

#define RAMDISK_SIZE (FSSIZE * BSIZE)  // 文件系统大小

// 内存中的"磁盘"数据
static char ramdisk[RAMDISK_SIZE];
static struct spinlock ramdisk_lock;
static int ramdisk_initialized = 0;

void
ramdisk_init(void)
{
  initlock(&ramdisk_lock, "ramdisk");
  memset(ramdisk, 0, RAMDISK_SIZE);
  ramdisk_initialized = 1;
  printf("ramdisk: initialized %d KB at %p\n", RAMDISK_SIZE / 1024, ramdisk);
}

// 从ramdisk读取块
void
ramdisk_rw(struct buf *b, int write)
{
  if(!ramdisk_initialized)
    panic("ramdisk_rw: ramdisk not initialized");
    
  if(b == 0)
    panic("ramdisk_rw: null buffer");
    
  if(b->blockno >= FSSIZE)
    panic("ramdisk_rw: blockno out of range");

  // 计算地址 - 使用更安全的方式
  uint64 block_offset = (uint64)b->blockno * (uint64)BSIZE;
  if(block_offset >= RAMDISK_SIZE) {
    printf("ramdisk_rw: block offset %lu out of range (max %d)\n", 
           block_offset, RAMDISK_SIZE - 1);
    panic("ramdisk_rw: block offset out of range");
  }
  
  char *ramdisk_addr = (char*)((uint64)ramdisk + block_offset);
  char *buf_data = (char*)&b->data[0];
  
  // 详细检查指针有效性
  if((uint64)ramdisk < KERNBASE) {
    printf("ramdisk_rw: ramdisk address %p below KERNBASE\n", ramdisk);
    panic("ramdisk_rw: ramdisk address invalid");
  }
  
  if((uint64)ramdisk_addr < (uint64)ramdisk) {
    printf("ramdisk_rw: ramdisk_addr %p < ramdisk %p\n", ramdisk_addr, ramdisk);
    panic("ramdisk_rw: ramdisk_addr calculation error");
  }
  
  if((uint64)ramdisk_addr + BSIZE > (uint64)ramdisk + RAMDISK_SIZE) {
    printf("ramdisk_rw: ramdisk_addr %p + %d exceeds ramdisk range\n", 
           ramdisk_addr, BSIZE);
    panic("ramdisk_rw: ramdisk_addr out of range");
  }
  
  if((uint64)buf_data == 0) {
    printf("ramdisk_rw: buf_data is NULL (b=%p)\n", b);
    panic("ramdisk_rw: buf_data is NULL");
  }
  
  if((uint64)buf_data < (uint64)b) {
    printf("ramdisk_rw: buf_data %p < b %p\n", buf_data, b);
    panic("ramdisk_rw: buf_data calculation error");
  }
  
  acquire(&ramdisk_lock);
  
  // 使用 memmove 而不是循环，但先检查参数
  if(write) {
    // 写入：从 b->data 复制到 ramdisk
    memmove(ramdisk_addr, buf_data, BSIZE);
  } else {
    // 读取：从 ramdisk 复制到 b->data
    memmove(buf_data, ramdisk_addr, BSIZE);
  }
  
  release(&ramdisk_lock);
}